﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Kinect.Toolbox.Collectors;
using Microsoft.Kinect;

namespace Kinect.Toolbox.Providers
{
    public class BinaryFilesFrameProvider : IFrameProvider
    {
        private bool _isRunned;

        public event EventHandler<FrameReadyEventArgs> FrameReady;
        public event EventHandler NoFramesLeft;

        public async void Start()
        {
            List<Frame> frames = new List<Frame>();
            await Task.Run(() =>
                {

                    _isRunned = true;
                    string recordingPath = ConfigurationManager.AppSettings["RecordFramesPath"] ?? Path.GetTempPath();
                    foreach (var path in Directory.GetFiles(recordingPath))
                    {
                        if (!_isRunned)
                        {
                            break;
                        }

                        using (Stream stream = File.Open(path, FileMode.Open))
                        {
                            var bin = new BinaryFormatter(); 
                            try
                            {

                                frames.AddRange((List<Frame>)bin.Deserialize(stream));
                            }
                            catch (Exception)
                            {
                                //TODO
                            }
                        }


                    }
                });

            ProvideFrames(frames);
            Stop();

        }

        public void Stop()
        {
            _isRunned = false;
            if (NoFramesLeft != null)
            {
                NoFramesLeft(this, EventArgs.Empty);
            }
        }

        private void ProvideFrames(List<Frame> frames)
        {
            var lastFrameTimestamp = frames.First().Timestamp;
            foreach (var frame in frames)
            {
                var frame1 = frame;
                var miliseconds = frame1.Timestamp - lastFrameTimestamp;
                var fromMilliseconds = TimeSpan.FromTicks(miliseconds);
                Thread.Sleep(fromMilliseconds);
                lastFrameTimestamp = frame1.Timestamp;
                if (FrameReady != null)
                {
                    FrameReady(this, new FrameReadyEventArgs(frame1));
                }
            }
        }
    }

}
